package org.zjt.link;

import org.apache.http.util.Asserts;

import java.util.List;
import java.util.Objects;

/**
 * @author juntao.zhang
 * @version V1.0
 * @Description: TODO
 * @Package org.zjt.link
 * @date 2018/4/21 21:12
 */
public class LinkTest {
    public static void main(String[] args) {

        LinkNode head = new LinkNode();
        LinkNode preNode = head;
        for(int i=0;i< 6;i++){
            LinkNode linkNode = new LinkNode(i,null);
            preNode.setRight(linkNode);
            preNode = linkNode;
        }

        preNode = head.getRight();
        while (Objects.nonNull(preNode)){
            System.out.printf("   %s",preNode.getValue());
            preNode = preNode.getRight();
        }

        System.out.println();

        LinkNode linkNode = reverseLink(head);
        preNode = linkNode;
        while (Objects.nonNull(preNode)){
            System.out.printf("   %s",preNode.getValue());
            preNode = preNode.getRight();
        }
    }

    /**
     * 递归，在反转当前节点之前先反转后续节点
     */
    public static LinkNode reverse1(LinkNode head) {
                                                        // head看作是前一结点，head.getRight()是当前结点，reHead是反转后新链表的头结点
        if (head == null || head.getRight() == null) {
            return head;                                // 若为空链或者当前结点在尾结点，则直接还回
        }
        LinkNode reHead = reverse1(head.getRight());    // 先反转后续节点head.getRight()

        head.getRight().setRight(head);                 // 将当前结点的指针域指向前一结点
        head.setRight(null);                            // 前一结点的指针域令为null;
        return reHead;                                  // 反转后新链表的头结点
    }


    /**
     * 1、将上一个节点信息保存，并复制给下一个元素的next。并返回一个新的头节点
     * @param head
     * @return
     */
    public static LinkNode reverseLink(LinkNode head) {
        Asserts.notNull(head,"empty link");
        LinkNode newHead = new LinkNode();
        LinkNode pre = null;
        LinkNode current = head;
        while (Objects.nonNull(current)){
            LinkNode right = current.getRight();
            if (Objects.isNull(right)){
                newHead.setRight(current);
            }
            current.setRight(pre);
            pre = current;
            current = right;
        }
        return newHead;
    }
}
